using System;
using System.Diagnostics.CodeAnalysis;
using Bookvar.ObjectModel;
using Bookvar.ObjectModel.Actions.Collaboration;
using Bookvar.ObjectModel.Collections;

namespace Bookvar.Collaboration
{
    /// <summary>
    /// This interface defines a facade for the Bookvar collaboration module.
    /// </summary>
    public interface ICollaborationManager
    {
        CollaborationMode CollaborationMode { get; }

        CollaborationUser CurrentCollaborationUser { get; }

        /// <summary>
        /// Gets the collaboration users. 
        /// </summary>
        /// <value>The collaboration users.</value>
        CollaborationUserCollection CollaborationUsers { get; }

        /// <summary>
        /// Starts the collaboration server.
        /// </summary>
        /// <exception cref="InvalidOperationException">If the collaboration server or client is already started.</exception>
        void StartServer(string hostName, MindMap map, Uri hostAddress);

        /// <summary>
        /// Starts the collaboration server with and address from the configuration.
        /// </summary>
        /// <exception cref="InvalidOperationException">If the collaboration server or client is already started.</exception>
        void StartServer(string hostName, MindMap map);

        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]
        void ConnectToServer(string uri);

        IAsyncResult BeginConnectToServer(string serverAddress,
                                          string clientName,
                                          AsyncCallback callback);

        CollaborationUser[] EndConnectToServer(IAsyncResult asyncResult);

        /// <summary>
        /// Stops the collaboration. 
        /// </summary>
        /// If the collaboraiton server is started it is stopped. If the client is started - it is disconnected.
        /// <exception cref="InvalidOperationException">If the collaboration server or client is not started or is already closed.</exception>
        void StopCollaboration();

        /// <summary>
        /// Says a message to all the collaboration users.
        /// </summary>
        /// <param name="message">The message.</param>
        void Say(string message);

        /// <summary>
        /// Whispers a message to the user with the specified unique key.
        /// </summary>
        /// <param name="userKey">The unique key for the user.</param>
        /// <param name="message">The message.</param>
        void Whisper(Guid userKey, string message);

        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Used as a method in service contract.")]
        MindMap GetMindmap();

        void SendAction(ActionBase action);

        event EventHandler ServerStopped;

        event EventHandler ConnectionToServerLost;

        event EventHandler ServerStarted;

        event EventHandler ClientConnected;

        event EventHandler CollaborationStopped;

        /// <summary>
        /// Occurs when an user says something.
        /// </summary>
        event EventHandler<CollaborationUserMessageEventArgs> UserSaid;

        /// <summary>
        /// Occurs when an user whispers something.
        /// </summary>
        event EventHandler<CollaborationUserMessageEventArgs> UserWhispered;

        /// <summary>
        /// Occurs when an user joins the collaboration session.
        /// </summary>
        event EventHandler<CollaborationUserEventArgs> UserJoined;

        /// <summary>
        /// Occurs when an user leaves the collaboration session.
        /// </summary>
        event EventHandler<CollaborationUserEventArgs> UserLeft;
    }
}